package com.baoyouqun.API.push;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baoyouqun.base.BusinessException;
import com.baoyouqun.entity.User;
import com.baoyouqun.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WechatServiceImpl implements WechatService {

    @Resource
    private WechatConfig wechatConfig;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private UserService userService; // 直接依赖用户服务获取openid

    @Override
    public void pushToUsers(String title, String content, List<String> userIds) {
        // 1. 从user表直接查询用户的openid（关键调整：无需关联中间表）
        List<User> users = userService.list(Wrappers.<User>lambdaQuery()
                .in(User::getId, userIds)
                .isNotNull(User::getWxOpenid));

        if (CollUtil.isEmpty(users)) {
            log.warn("没有找到有效的用户openid，userId列表：{}", userIds);
            return;
        }

        // 提取有效的openid列表
        List<String> openids = users.stream()
                .map(User::getWxOpenid)
                .collect(Collectors.toList());

        // 2. 获取微信access_token（使用SaToken缓存）
        String accessToken = getAccessToken();

        // 3. 调用微信模板消息接口推送
        String pushUrl = WechatConstant.TEMPLATE_MESSAGE_URL.replace("ACCESS_TOKEN", accessToken);
        for (String openid : openids) {
            try {
                Map<String, Object> message = buildTemplateMessage(openid, title, content, LocalDateTime.now().toString());
                String result = restTemplate.postForObject(pushUrl, message, String.class);
                log.info("推送结果：{}，openid：{}", result, openid);

                // 处理错误响应
                JSONObject resultMap = JSONUtil.parseObj(result);
                if (!"0".equals(resultMap.get("errcode").toString())) {
                    log.error("推送失败：{}，openid：{}", result, openid);
                }
            } catch (Exception e) {
                log.error("推送异常，openid：{}", openid, e);
            }
        }
    }

    /**
     * 获取access_token（使用SaToken缓存，有效期2小时）
     */
    private String getAccessToken() {
        // SaToken缓存key（区分不同公众号）
        String cacheKey = "wechat:access_token:" + wechatConfig.getAppId();

        // 从SaToken缓存获取
        Object cacheToken = StpUtil.getSession().getString(cacheKey);
        if (cacheToken != null) {
            return cacheToken.toString();
        }

        // 缓存未命中，调用微信接口获取
        String url = WechatConstant.ACCESS_TOKEN_URL
                .replace("APPID", wechatConfig.getAppId())
                .replace("SECRET", wechatConfig.getSecret());

        String result = restTemplate.getForObject(url, String.class);
//        Map<String, Object> resultMap = JsonUtil.toMap(result);
        JSONObject resultMap = JSONUtil.parseObj(result);

        // 处理错误
        if (resultMap.containsKey("errcode") && !"0".equals(resultMap.get("errcode").toString())) {
            log.error("获取access_token失败：{}", result);
            throw new BusinessException("微信接口错误：" + resultMap.get("errmsg"));
        }

        // 缓存access_token（有效期110分钟，避免过期）
        String accessToken = resultMap.get("access_token").toString();
        StpUtil.getSession().set(cacheKey, accessToken);
        return accessToken;
    }

    /**
     * 构造微信模板消息（根据你的模板格式调整）
     */
    private Map<String, Object> buildTemplateMessage(
            String openid,
            String noticeTitle,
            String noticeContent,
            String noticeTime) {
        Map<String, Object> data = new HashMap<>();

        // 公告标题（thing6.DATA）
        data.put("thing6", Map.of("value", noticeTitle, "color", "#173177"));
        // 通知内容（thing2.DATA）
        data.put("thing2", Map.of("value", noticeContent, "color", "#173177"));
        // 通知时间（time3.DATA）
        data.put("time3", Map.of("value", noticeTime, "color", "#173177"));

        Map<String, Object> message = new HashMap<>();
        message.put("touser", openid); // 接收者openid
        message.put("template_id", wechatConfig.getTemplateId()); // 模板ID（需与公众号后台一致）
        message.put("url", wechatConfig.getJumpUrl()); // 点击消息跳转的URL
        message.put("data", data);
        return message;
    }
}